package com.weiiew.backend.utils.listener;

import com.weiiew.backend.entity.KeyInfo;
import com.weiiew.backend.operationUtils.KeyCode;
import lombok.extern.slf4j.Slf4j;
import org.jnativehook.keyboard.NativeKeyAdapter;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
@Component
public class FirstKeyListener extends NativeKeyAdapter {

    private final ListenerManager manager;
    private final AtomicBoolean isListening = new AtomicBoolean(false);
    private CallBack callBack = null;
    private final Object lock = new Object(); // 添加锁对象

    public FirstKeyListener(ListenerManager manager) {
        this.manager = manager;
        manager.registerKeyListener("firstKey", this);
    }

    public void startFirstKeyListener(CallBack callBack) {
        synchronized (lock) {
            // 重置状态以避免之前的回调残留
            isListening.set(false);
            // 设置新的回调和监听状态
            this.callBack = callBack;
            isListening.set(true);
        }
    }

    @Override
    public void nativeKeyPressed(NativeKeyEvent event) {
        CallBack currentCallback = null;
        KeyInfo keyInfo = null;

        synchronized (lock) {
            if (isListening.get() && !isModifierKey(event.getKeyCode())) {
                currentCallback = this.callBack;
                // 立即重置状态，防止重复触发
                isListening.set(false);
                this.callBack = null;
                keyInfo = parseKeyInfo(event);
            }
        }

        if (currentCallback != null && keyInfo != null) {
            currentCallback.callBack(keyInfo);
        }
    }

    @PreDestroy
    public void cleanup() {
        manager.unregisterKeyListener("firstKey");
    }

    private KeyInfo parseKeyInfo(NativeKeyEvent event) {
        int modifiers = event.getModifiers();
        return new KeyInfo(
                KeyCode.fromNativeEvent(event),
                (modifiers & NativeKeyEvent.SHIFT_MASK) != 0,
                (modifiers & NativeKeyEvent.CTRL_MASK) != 0,
                (modifiers & NativeKeyEvent.ALT_MASK) != 0,
                (modifiers & NativeKeyEvent.META_MASK) != 0,
                0,
                0
        );
    }

    private boolean isModifierKey(int keyCode) {
        return keyCode == NativeKeyEvent.VC_SHIFT
                || keyCode == NativeKeyEvent.VC_CONTROL
                || keyCode == NativeKeyEvent.VC_ALT
                || keyCode == NativeKeyEvent.VC_META;
    }

    public interface CallBack {
        void callBack(KeyInfo info);
    }
}